#if defined(__NIM_LINUX_PLATFORM__)
#include "tun_tda18250_linux.h"
#elif defined(__NIM_TDS_PLATFORM__)
#include "tun_tda18250_tds.h"
#endif



#if 0
#define TDA18250_PRINTF 	nim_print
#else
#define TDA18250_PRINTF(...) 
#endif



#define MAX_TUNER_SUPPORT_NUM 2//1
#define NIM_TUNER_SET_STANDBY_CMD	0xffffffff
#define BURST_SZ 14

static struct QAM_TUNER_CONFIG_EXT * tda18250_dev_id[MAX_TUNER_SUPPORT_NUM] = {NULL};
static UINT32 tda18250_tuner_cnt = 0;

static UINT32 tda18250_tuner_i2c = 0;//I2C_TYPE_SCB0;

#if defined(__NIM_LINUX_PLATFORM__)
static struct mutex  g_mutex_lock;
#elif defined(__NIM_TDS_PLATFORM__)
static UINT32        g_mutex_lock=OSAL_INVALID_ID;
#endif

static UINT32 g_mutex_lock_arr[2] = {0,0};


//*--------------------------------------------------------------------------------------
//* Prototype of function to be provided by customer
//*--------------------------------------------------------------------------------------
tmErrorCode_t 	UserWrittenI2CRead(tmUnitSelect_t tUnit,UInt32 AddrSize, UInt8* pAddr,UInt32 ReadLen, UInt8* pData);
tmErrorCode_t 	UserWrittenI2CWrite (tmUnitSelect_t tUnit, UInt32 AddrSize, UInt8* pAddr,UInt32 WriteLen, UInt8* pData);
tmErrorCode_t 	UserWrittenWait(tmUnitSelect_t tUnit, UInt32 tms);
tmErrorCode_t 	UserWrittenPrint(UInt32 level, const char* format, ...);
tmErrorCode_t  	UserWrittenMutexInit(ptmbslFrontEndMutexHandle *ppMutexHandle);
tmErrorCode_t  	UserWrittenMutexDeInit( ptmbslFrontEndMutexHandle pMutex);
tmErrorCode_t  	UserWrittenMutexAcquire(ptmbslFrontEndMutexHandle pMutex, UInt32 timeOut);
tmErrorCode_t  	UserWrittenMutexRelease(ptmbslFrontEndMutexHandle pMutex);


//*--------------------------------------------------------------------------------------
//* Template of function to be provided by customer
//*--------------------------------------------------------------------------------------

//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenI2CRead
//* Object              : 
//* Input Parameters    : 	tmUnitSelect_t tUnit
//* 						UInt32 AddrSize,
//* 						UInt8* pAddr,
//* 						UInt32 ReadLen,
//* 						UInt8* pData
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------
tmErrorCode_t UserWrittenI2CRead(tmUnitSelect_t tUnit,	UInt32 AddrSize, UInt8* pAddr,UInt32 ReadLen, UInt8* pData)
{
   	tmErrorCode_t err = TM_OK;
	INT32 result = 0;
	UINT8 u8_add = (0xc0 & 0xff);

	if (AddrSize != 1)
	{
		TDA18250_PRINTF("TDA18250 error 1!\n");		
	}

	if (ReadLen > 15)
	{
		TDA18250_PRINTF("TDA18250 error 2 !\n");
	}

	pData[0] = pAddr[0];

	result = nim_i2c_write_read(tda18250_tuner_i2c, u8_add, pData, 1, ReadLen);

	if (result == SUCCESS)
	{
		err = TM_OK;
	}
	else
	{
		err = !TM_OK;
	}


   return err;
}

//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenI2CWrite
//* Object              : 
//* Input Parameters    : 	tmUnitSelect_t tUnit
//* 						UInt32 AddrSize,
//* 						UInt8* pAddr,
//* 						UInt32 WriteLen,
//* 						UInt8* pData
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------

tmErrorCode_t UserWrittenI2CWrite (tmUnitSelect_t tUnit, 	UInt32 AddrSize, UInt8* pAddr,UInt32 WriteLen, UInt8* pData)
{
   	tmErrorCode_t err = TM_OK;
	INT32 result = 0;
	UINT8 data[BURST_SZ+1]; // every time, write 14 byte..
	INT32 RemainLen, BurstNum;
	INT32 i,j;

	UINT8 u8_add = (0xc0 & 0xff);

	if (AddrSize != 1)
	{
		TDA18250_PRINTF("TDA18250 error 1 !\n");
		
	}
	
	RemainLen = WriteLen % BURST_SZ; 
	if (RemainLen)
	{
		BurstNum = WriteLen / BURST_SZ; 
	}
	else
	{
		BurstNum = WriteLen / BURST_SZ - 1;
		RemainLen = BURST_SZ;
	}

	for ( i = 0 ; i < BurstNum; i ++ )
	{
		for ( j = 0 ; j < BURST_SZ ; j++  )
		{
			data[j+1]   = pData[i * BURST_SZ + j ];
		}
		data[0] = pAddr[0]+i*BURST_SZ;

		result |= nim_i2c_write(tda18250_tuner_i2c, u8_add, data, BURST_SZ+1);

	}

	for ( i = 0 ; i < RemainLen ; i++ )
	{
		data[i+1]   = pData[BurstNum * BURST_SZ + i ];
		data[0] = pAddr[0]+BurstNum*BURST_SZ;
	}

	result |= nim_i2c_write(tda18250_tuner_i2c, u8_add, data, RemainLen+1);

	if (result == SUCCESS)
	{
		err = TM_OK;
	}
	else
	{
		err = !TM_OK;
	}

   return err;
}

//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenWait
//* Object              : 
//* Input Parameters    : 	tmUnitSelect_t tUnit
//* 						UInt32 tms
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------
tmErrorCode_t UserWrittenWait(tmUnitSelect_t tUnit, UInt32 tms)
{
	comm_sleep(tms);

   return TM_OK;
}

//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenPrint
//* Object              : 
//* Input Parameters    : 	UInt32 level, const char* format, ...
//* 						
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------
tmErrorCode_t 			UserWrittenPrint(UInt32 level, const char* format, ...)
{

   return TM_OK;
}

//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenMutexInit
//* Object              : 
//* Input Parameters    : 	ptmbslFrontEndMutexHandle *ppMutexHandle
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------
tmErrorCode_t  UserWrittenMutexInit(ptmbslFrontEndMutexHandle *ppMutexHandle)
{
	static UINT8 mux_cnt = 0;
	
#if defined(__NIM_LINUX_PLATFORM__)
 	
	mutex_init(&g_mutex_lock);
	g_mutex_lock_arr[mux_cnt] = (UINT32)(&g_mutex_lock);
#elif defined(__NIM_TDS_PLATFORM__)
	
	g_mutex_lock=osal_mutex_create();	
	if(g_mutex_lock == OSAL_INVALID_ID)	
	{
		TDA18250_PRINTF("i2c mutex error\n");
	}
	g_mutex_lock_arr[mux_cnt] = g_mutex_lock;
	
#endif
	//*ppMutexHandle = (ptmbslFrontEndMutexHandle*)&g_mutex_lock;
	*ppMutexHandle = (void*)&g_mutex_lock_arr[mux_cnt];

	//TDA18250_PRINTF("[%s]line=%d,end pMute=0x%x!\n", __FUNCTION__,__LINE__,*ppMutexHandle);
	mux_cnt += 1;
	
	//

   return TM_OK;
}


//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenMutexDeInit
//* Object              : 
//* Input Parameters    : 	 ptmbslFrontEndMutexHandle pMutex
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------
tmErrorCode_t  UserWrittenMutexDeInit( ptmbslFrontEndMutexHandle pMutex)
{

#if defined(__NIM_LINUX_PLATFORM__)
	mutex_destroy((struct mutex *)pMutex);
#elif defined(__NIM_TDS_PLATFORM__)
	osal_mutex_delete(*((OSAL_ID*)pMutex));
#endif

   return TM_OK;
}



//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenMutexAcquire
//* Object              : 
//* Input Parameters    : 	ptmbslFrontEndMutexHandle pMutex, UInt32 timeOut
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------
tmErrorCode_t  UserWrittenMutexAcquire(ptmbslFrontEndMutexHandle pMutex, UInt32 timeOut)
{
	TDA18250_PRINTF("[%s]line=%d,enter pMute=0x%x!\n", __FUNCTION__,__LINE__,pMutex);
	
#if defined(__NIM_LINUX_PLATFORM__)
	//mutex_lock((struct mutex *)pMutex);
	char i;
    for (i=0; i<4; i++)
    {
       if (0 == mutex_trylock((struct mutex *)pMutex))
       {
            break;
        }
        comm_sleep(timeOut/3400);  //timeOut = TDA18250_MUTEX_TIMEOUT(5000) need improve
    }
  
#elif defined(__NIM_TDS_PLATFORM__)

	osal_mutex_lock(*((OSAL_ID*)pMutex), timeOut);

#endif
	TDA18250_PRINTF("[%s]line=%d,end!\n", __FUNCTION__,__LINE__);
    return TM_OK;
}

//*--------------------------------------------------------------------------------------
//* Function Name       : UserWrittenMutexRelease
//* Object              : 
//* Input Parameters    : 	ptmbslFrontEndMutexHandle pMutex
//* Output Parameters   : tmErrorCode_t.
//*--------------------------------------------------------------------------------------
tmErrorCode_t  UserWrittenMutexRelease(ptmbslFrontEndMutexHandle pMutex)
{

#if defined(__NIM_LINUX_PLATFORM__)
	mutex_unlock((struct mutex *)pMutex);
#elif defined(__NIM_TDS_PLATFORM__)
	osal_mutex_unlock(*((OSAL_ID*)pMutex));
#endif


   return TM_OK;
}

	
INT32 tun_tda18250_init(UINT32* tuner_id, struct QAM_TUNER_CONFIG_EXT * ptrTuner_Config)
{
	/* check Tuner Configuration structure is available or not */
	
	if ((ptrTuner_Config == NULL) || (tda18250_tuner_cnt>=MAX_TUNER_SUPPORT_NUM))
	{
		TDA18250_PRINTF("[%s]line=%d,error,back!\n",__FUNCTION__,__LINE__);
		return ERR_FAILUE;
	}	
	
	TDA18250_PRINTF("[%s]line=%d,enter i2c_type_id=0x%x!\n", __FUNCTION__,__LINE__,ptrTuner_Config->i2c_type_id);
	
	tda18250_tuner_i2c = ptrTuner_Config->i2c_type_id;
	tda18250_dev_id[tda18250_tuner_cnt] = ptrTuner_Config;
	*tuner_id = tda18250_tuner_cnt;

	tda18250_tuner_cnt ++;

	TDA18250_PRINTF("[%s] end !\n", __FUNCTION__);
	
	return SUCCESS;
}


INT32 tun_tda18250_close(UINT32 tuner_id)
{
#ifndef TWO_TUNER_SUPPORT
	tda18250_tuner_cnt = 0;
#else
	if (0 >= tda18250_tuner_cnt)
		return SUCCESS;
	tda18250_tuner_cnt--;
#endif
	return SUCCESS;
}



INT32 tun_tda18250_status(UINT32 tuner_id, UINT8 *lock)
{
	INT32 result = 0;
	tmErrorCode_t err;
	tmbslFrontEndState_t PLLLockMaster = tmbslFrontEndStateUnknown;	
	
	struct QAM_TUNER_CONFIG_EXT * tuner_dev_ptr = NULL;

	TDA18250_PRINTF("[%s]line=%d,enter!\n", __FUNCTION__,__LINE__);
	
	if ((tuner_id>=tda18250_tuner_cnt) || (tuner_id>=MAX_TUNER_SUPPORT_NUM))
		return ERR_FAILUE;
	tuner_dev_ptr = tda18250_dev_id[tuner_id];

   /* Get TDA18250 Master PLL Lock status */
	err = tmbslTDA18250GetLockStatus(0, &PLLLockMaster);
	if(err != TM_OK)
	{
		*lock = 0;
		result = !SUCCESS;
	}
	else
	{
		if (tmbslFrontEndStateLocked == PLLLockMaster)
		{
			*lock = 1;
		}
		else
		{
			*lock = 0;
		}
		result = SUCCESS;
	}
   TDA18250_PRINTF("[%s]line=%d,end!\n", __FUNCTION__,__LINE__);
	return result;
}

INT32 tun_tda18250_control(UINT32 tuner_id, UINT32 freq, UINT32 sym, UINT8 AGC_Time_Const, UINT8 _i2c_cmd)	
{	

	INT32   result;
	tmErrorCode_t err;
	static INT8 tun_status=0;

	UInt32 uRFMaster = freq*1000;

	TDA18250_PRINTF("[%s]line=%d,enter!\n", __FUNCTION__,__LINE__);	
	if (0==tun_status)
	{
	   /* Variable declarations */
	   tmErrorCode_t err = TM_OK;
	   tmbslFrontEndDependency_t sSrvTunerFunc;

	   tmTDA18250StandardMode_t stdModeMaster = tmTDA18250_DIG_9MHz;
	   
	/* Low layer struct set-up to link with user written functions */
	   sSrvTunerFunc.sIo.Write             = UserWrittenI2CWrite;
	   sSrvTunerFunc.sIo.Read              = UserWrittenI2CRead;
	   sSrvTunerFunc.sTime.Get             = Null;
	   sSrvTunerFunc.sTime.Wait            = UserWrittenWait;
	   sSrvTunerFunc.sDebug.Print          = UserWrittenPrint;
	   sSrvTunerFunc.sMutex.Init           = UserWrittenMutexInit;
	   sSrvTunerFunc.sMutex.DeInit         = UserWrittenMutexDeInit;
	   sSrvTunerFunc.sMutex.Acquire        = UserWrittenMutexAcquire;
	   sSrvTunerFunc.sMutex.Release        = UserWrittenMutexRelease;
	   sSrvTunerFunc.dwAdditionalDataSize  = 0;
	   sSrvTunerFunc.pAdditionalData       = Null;
	   
	   /* TDA18250 Master Driver low layer setup */
	   err = tmbslTDA18250Init(0, &sSrvTunerFunc);
	   if(err != TM_OK)
	       return err;
	   
	   /* TDA18250 Master Hardware initialization */
	   err = tmbslTDA18250Reset(0);
	   if(err != TM_OK)
	       return err;
	   
	   /* TDA18250 Master Hardware power state */
	   err = tmbslTDA18250SetPowerState(0, tmTDA18250_PowerNormalMode);
	   if(err != TM_OK)
	       return err;


	   /* TDA18250 Master standard mode */
	   err = tmbslTDA18250SetStandardMode(0, stdModeMaster);
	   if(err != TM_OK)
	       return err;

		tun_status = 1;
	}
	
		//kent,2013-7-13
	if( freq == NIM_TUNER_SET_STANDBY_CMD )
	{
		if( sym==0 )
		{
			TDA18250_PRINTF("[%s]line=%d,standby!!\n",__FUNCTION__,__LINE__);
			tmbslTDA18250SetPowerState(0, tmTDA18250_PowerStandbyWithLoopThroughOnAndWithXtalOn);
		}
		else if(sym==1)
		{
			tmbslTDA18250SetPowerState(0, tmTDA18250_PowerNormalMode);			
		}
		else
		{
			return ERR_FAILED;
		}

		TDA18250_PRINTF("[%s]line=%d,standby,return!!\n",__FUNCTION__,__LINE__);
		return SUCCESS;

		
	}

   /* TDA18250 Master RF frequency */
   err = tmbslTDA18250SetRf(0, uRFMaster);
   if(err != TM_OK)
       return err;
	
	comm_sleep(100);

	if (err !=TM_OK) 
	{
		result= ERR_FAILED;
	}
	else
	{
		result = SUCCESS;
	}

	TDA18250_PRINTF("[%s]line=%d,end!\n", __FUNCTION__,__LINE__);

	return result;

}

